#!/bin/bash

export LC_ALL=C
unset ANLOGIC_CFG_TOOLCHAIN

err_handler() {
	ret=$?
	[ "$ret" -eq 0 ] && return

	echo "ERROR: Running ${FUNCNAME[1]} failed!"
	echo "ERROR: exit code $ret from line ${BASH_LINENO[0]}:"
	echo "    $BASH_COMMAND"
	exit $ret
}
trap 'err_handler' ERR
set -eE

function finish_build(){
	echo -e "Running ${FUNCNAME[1]} succeeded.\n"
	cd $TOP_DIR
}

function check_config(){
	unset missing
	for var in $@; do
		eval [ \$$var ] && continue

		missing="$missing $var"
	done

	[ -z "$missing" ] && return 0

	echo "Skipping ${FUNCNAME[1]} for missing configs: $missing."
	return 1
}

function choose_target_board()
{
	echo
	echo "You're building on Linux"
	echo "Lunch menu...pick a combo:"
	echo ""

	echo "0. default BoardConfig.mk"
	echo ${ANLOGIC_TARGET_BOARD_ARRAY[@]} | xargs -n 1 | sed "=" | sed "N;s/\n/. /"

	local INDEX
	read -p "Which would you like? [0]: " INDEX
	INDEX=$((${INDEX:-0} - 1))

	if echo $INDEX | grep -vq [^0-9]; then
		ANLOGIC_BUILD_TARGET_BOARD="${ANLOGIC_TARGET_BOARD_ARRAY[$INDEX]}"
	else
		echo "Lunching for Default BoardConfig.mk boards..."
		ANLOGIC_BUILD_TARGET_BOARD=BoardConfig.mk
	fi
}

function build_select_board()
{
	ANLOGIC_TARGET_BOARD_ARRAY=( $(cd ${TARGET_PRODUCT_DIR}/; ls BoardConfig*.mk | sort) )

	ANLOGIC_TARGET_BOARD_ARRAY_LEN=${#ANLOGIC_TARGET_BOARD_ARRAY[@]}
	if [ $ANLOGIC_TARGET_BOARD_ARRAY_LEN -eq 0 ]; then
		echo "No available Board Config"
		echo "Run ./envsetup.sh to select fpsoc"
		return
	fi

	choose_target_board

	#ln -rfs $TARGET_PRODUCT_DIR/$ANLOGIC_BUILD_TARGET_BOARD device/.BoardConfig.mk
	ln -rfs $TARGET_PRODUCT_DIR/$ANLOGIC_BUILD_TARGET_BOARD $BOARD_CONFIG
	echo "switching to board: `realpath $BOARD_CONFIG`"
}

function unset_board_config_all()
{
	local tmp_file=`mktemp`
	grep -oh "^export.*ANLOGIC_.*=" `find device -name "BoardConfig.mk"` > $tmp_file

	source $tmp_file
	rm -f $tmp_file
}

CMD=`realpath $0`
COMMON_DIR=`dirname $CMD`
TOP_DIR=$(realpath $COMMON_DIR)
cd $TOP_DIR

BOARD_CONFIG=$TOP_DIR/device/.BoardConfig.mk
TARGET_PRODUCT=$TOP_DIR/device/$TARGET_DIR_NAME
TARGET_PRODUCT_DIR=$(realpath ${TARGET_PRODUCT})

#if [ ! -L "$BOARD_CONFIG" -a  "$1" != "lunch" ]; then
#	build_select_board
#fi
unset_board_config_all
[ -L "$BOARD_CONFIG" ] && source $BOARD_CONFIG

function usage()
{
	echo "Usage: build.sh [OPTIONS]"
	echo "Available options:"
	echo "lunch               -list current SDK boards and switch to specified board config"
	echo "fsbl                -build fsbl"
	echo "opensbi             -build opensbi"
	echo "uboot               -build uboot"
	echo "ubootmenuconfig     -build uboot menuconfig"
	echo "kernel              -build kernel"
	echo "kernelmenuconfig    -build kernel menuconfig"
	echo "buildroot           -build buildroot rootfs"
	echo "buildrootmenuconfig -build buildroot menuconfig"
	echo "busyboxmenuconfig   -build busybox menuconfig"
	echo "bootscr             -build boot script"
	echo "bootgen             -build bootgen"
	echo "partition           -build partition"
	echo "bootpart            -build boot partition image"
	echo "extrafiles          -build extrafiles of image"
	echo "all                 -build uboot, kernel, rootfs, bootscr, bootgen, images"
	echo "cleanfsbl           -clean fsbl"
	echo "cleanopensbi        -clean opensbi"
	echo "cleanuboot          -clean uboot"
	echo "cleankernel         -clean kernel"
	echo "cleanbuildroot      -clean buildroot rootfs"
	echo "cleanbootscr        -clean boot script"
	echo "cleanbootgen        -clean bootgen"
	echo "cleanpartition      -clean partition"
	echo "cleanbootpart       -clean boot partition image"
	echo "cleanextrafiles     -clean extrafiles of image"
	echo "cleanall            -clean uboot, kernel, rootfs, bootscr, bootgen, images"
	echo ""
}

function build_info(){
	if [ ! -L $TARGET_PRODUCT_DIR ];then
		echo "No found target product!!!"
	fi
	if [ ! -L $BOARD_CONFIG ];then
		echo "No found target board config!!!"
	fi

	echo "Current Building Information:"
	echo "Target Product: $TARGET_PRODUCT_DIR"
	echo "Target BoardConfig: `realpath $BOARD_CONFIG`"
	echo "Target Misc config:"
	echo "`env |grep "^ANLOGIC_" | grep -v "=$" | sort`"
}

function build_opensbi(){
	check_config ANLOGIC_OPENSBI || return 0
	OPENSBI_DIR=$TOP_DIR/opensbi
	TARGET_OPENSBI_OUTPUT_DIR=$TOP_DIR/$TARGET_OPENSBI_OUTPUT_DIR

	echo "============Start building loader============"
	echo "TARGET_OPENSBI_DIR	      =$OPENSBI_DIR"
	echo "TARGET_OPENSBI_OUTPUT_DIR=$TARGET_OPENSBI_OUTPUT_DIR"
	echo "============================================="

	mkdir -p $TARGET_OPENSBI_OUTPUT_DIR || return

	make -C $OPENSBI_DIR O=$TARGET_OPENSBI_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN \
		FW_TEXT_START=${ANLOGIC_OPENSBI_BASE} \
		FW_JUMP_ADDR=${ANLOGIC_OPENSBI_JUMP} \
		PLATFORM_RISCV_ABI=lp64 \
		PLATFORM_RISCV_ISA=rv64imafdc \
		PLATFORM=anlogic/${ANLOGIC_OPENSBI_PLATFORM} \
		AL_BOARD=${ANLOGIC_OPENSBI_BOARD}

	finish_build
}

function build_cleanopensbi(){
	check_config ANLOGIC_OPENSBI || return 0
	rm -rf $TARGET_OPENSBI_OUTPUT_DIR
	finish_build
}

function build_uboot(){
	check_config ANLOGIC_UBOOT_DEFCONFIG || return 0
	UBOOT_DIR=$TOP_DIR/u-boot
	TARGET_UBOOT_OUTPUT_DIR=$TOP_DIR/$TARGET_UBOOT_OUTPUT_DIR

	echo "============Start building uboot============"
	echo "TARGET_UBOOT_DIR        = $UBOOT_DIR"
	echo "TARGET_UBOOT_CONFIG     = $ANLOGIC_UBOOT_DEFCONFIG"
	echo "TARGET_UBOOT_OUTPUT_DIR = $TARGET_UBOOT_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_UBOOT_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR $ANLOGIC_UBOOT_DEFCONFIG
	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN olddefconfig
	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN DEVICE_TREE=`basename -s .dts ${ANLOGIC_UBOOT_DTS}` all

	finish_build
}

function build_fsbl(){
	echo "============Start building fsbl============"
	echo "TARGET_DIR        = $TOP_DIR/device/$TARGET_DIR_NAME/"
	echo "MASTER_SDK_DIR    = $TOP_DIR/master_sdk"
	echo "============================================"

	rm -rf $HPF_UNZIP_DIR/HPFs
	unzip $TOP_DIR/device/$TARGET_DIR_NAME/*.hpf -d $HPF_UNZIP_DIR

	# bitfile
	HPF_BIT_DIR=${HPF_UNZIP_DIR}/HPFs
	HPF_BITFILE=(
		$(ls ${HPF_BIT_DIR}/ | grep ".bit" | sort)
	)

	HPF_BITFILE_ARRAY_LEN=${#HPF_BITFILE[@]}
	if [ "$HPF_BITFILE_ARRAY_LEN" == 1 ];then
		cp ${HPF_BIT_DIR}/${HPF_BITFILE} $TOP_DIR/device/$TARGET_DIR_NAME/

		BOOTGEN_BIF=$TOP_DIR/device/$TARGET_DIR_NAME/$ANLOGIC_BOOTGEN_CONFIG
		start_char="${TARGET_DIR_NAME}\/"
		end_char=".bit"

		sed -i "s/${start_char}.*${end_char}/${start_char}${HPF_BITFILE}/" "$BOOTGEN_BIF"
	fi

	HPF_FILE_SRC_LEN=${#HPF_FILE_SRC[@]}
	for ((i=0; i<$HPF_FILE_SRC_LEN; i++)); do
		rm -rf ${HPF_FILE_DST[$i]}
		cp ${HPF_FILE_SRC[$i]} ${HPF_FILE_DST[$i]}
	done

	cd $MASTER_SDK_DIR/solutions/demo/fsbl/
	make CHIP=$ANLOGIC_TARGET_PRODUCT
	cp $MASTER_SDK_DIR/solutions/demo/fsbl/*.elf $TOP_DIR/device/$TARGET_DIR_NAME/
	finish_build
}

function build_cleanfsbl(){
	rm -rf $HPF_UNZIP_DIR/HPFs
	cd $MASTER_SDK_DIR/solutions/demo/fsbl/
	make CHIP=$ANLOGIC_TARGET_PRODUCT clean
	finish_build
}

function build_cleanuboot(){
	rm -rf $TARGET_UBOOT_OUTPUT_DIR
	rm -rf $TARGET_IMG_OUTPUT_DIR/u-boot.bin
	finish_build
}

function menuconfig_uboot(){
	check_config ANLOGIC_UBOOT_DEFCONFIG || return 0
	UBOOT_DIR=$TOP_DIR/u-boot
	TARGET_UBOOT_OUTPUT_DIR=$TOP_DIR/$TARGET_UBOOT_OUTPUT_DIR

	echo "============Start building uboot============"
	echo "TARGET_UBOOT_DIR        = $UBOOT_DIR"
	echo "TARGET_UBOOT_CONFIG     = $ANLOGIC_UBOOT_DEFCONFIG"
	echo "TARGET_UBOOT_OUTPUT_DIR = $TARGET_UBOOT_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_UBOOT_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR $ANLOGIC_UBOOT_DEFCONFIG
	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR menuconfig
	make -C $UBOOT_DIR O=$TARGET_UBOOT_OUTPUT_DIR savedefconfig
	mv -f $TARGET_UBOOT_OUTPUT_DIR/defconfig $UBOOT_DIR/configs/$ANLOGIC_UBOOT_DEFCONFIG

	finish_build
}

function build_kernel(){
	check_config ANLOGIC_KERNEL_DTS ANLOGIC_KERNEL_DEFCONFIG || return 0
	KERNEL_DIR=$TOP_DIR/linux
	TARGET_KERNEL_OUTPUT_DIR=$TOP_DIR/$TARGET_KERNEL_OUTPUT_DIR

	echo "============Start building kernel============"
	echo "TARGET_KERNEL_DIR        = $KERNEL_DIR"
	echo "TARGET_ARCH              = $ANLOGIC_ARCH"
	echo "TARGET_KERNEL_CONFIG     = $ANLOGIC_KERNEL_DEFCONFIG"
	echo "TARGET_KERNEL_DTS        = $ANLOGIC_KERNEL_DTS"
	echo "TARGET_KERNEL_OUTPUT_DIR = $TARGET_KERNEL_OUTPUT_DIR"
	echo "============================================="

	mkdir -p $TARGET_KERNEL_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR mrproper
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR $ANLOGIC_KERNEL_DEFCONFIG
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN olddefconfig
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN dtbs
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR CROSS_COMPILE=$TOP_DIR/$ANLOGIC_TOOLCHAIN -j$ANLOGIC_JOBS

	#gzip
	mkimage -A $ANLOGIC_ARCH -O linux -T kernel -C gzip -a 0x00400000 -e 0x00400000 -n Linux \
			-d $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/Image.gz \
			   $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/uImage.gz

	#lz4
	lz4 $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/Image $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/Image.lz4 -f -9
	mkimage -A $ANLOGIC_ARCH -O linux -T kernel -C lz4 -a 0x00400000 -e 0x00400000 -n Linux \
			-d $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/Image.lz4 \
			   $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/uImage.lz4


	cp $TARGET_KERNEL_OUTPUT_DIR/arch/$ANLOGIC_ARCH/boot/uImage.lz4 $TARGET_IMG_OUTPUT_DIR
	cp $TOP_DIR/$ANLOGIC_KERNEL_DTB $TARGET_IMG_OUTPUT_DIR

	finish_build
}

function build_cleankernel(){
	rm -rf $TARGET_KERNEL_OUTPUT_DIR
	rm -rf $TARGET_IMG_OUTPUT_DIR/uImage.lz4
	rm -rf $TARGET_IMG_OUTPUT_DIR/*.dtb
	finish_build
}

function menuconfig_kernel(){
	check_config ANLOGIC_KERNEL_DTS ANLOGIC_KERNEL_DEFCONFIG || return 0
	KERNEL_DIR=$TOP_DIR/linux
	TARGET_KERNEL_OUTPUT_DIR=$TOP_DIR/$TARGET_KERNEL_OUTPUT_DIR

	echo "============Start building kernel============"
	echo "TARGET_KERNEL_DIR        = $KERNEL_DIR"
	echo "TARGET_ARCH              = $ANLOGIC_ARCH"
	echo "TARGET_KERNEL_CONFIG     = $ANLOGIC_KERNEL_DEFCONFIG"
	echo "TARGET_KERNEL_DTS        = $ANLOGIC_KERNEL_DTS"
	echo "TARGET_KERNEL_OUTPUT_DIR = $TARGET_KERNEL_OUTPUT_DIR"
	echo "============================================="

	mkdir -p $TARGET_KERNEL_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR $ANLOGIC_KERNEL_DEFCONFIG
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR menuconfig
	make ARCH=$ANLOGIC_ARCH -C $KERNEL_DIR O=$TARGET_KERNEL_OUTPUT_DIR savedefconfig
	mv -f $TARGET_KERNEL_OUTPUT_DIR/defconfig $KERNEL_DIR/arch/$ANLOGIC_ARCH/configs/$ANLOGIC_KERNEL_DEFCONFIG

	finish_build
}

function build_buildroot(){
	check_config ANLOGIC_BUILDROOT_DEFCONFIG || return 0
	BUILDROOT_DIR=$TOP_DIR/buildroot
	TARGET_BUILDROOT_OUTPUT_DIR=$TOP_DIR/$TARGET_BUILDROOT_OUTPUT_DIR

	echo "==========Start building buildroot=========="
	echo "TARGET_BUILDROOT_DIR        = $BUILDROOT_DIR"
	echo "TARGET_BUILDROOT_CONFIG     = $ANLOGIC_BUILDROOT_DEFCONFIG"
	echo "TARGET_BUILDROOT_OUTPUT_DIR = $TARGET_BUILDROOT_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_BUILDROOT_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR $ANLOGIC_BUILDROOT_DEFCONFIG
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR olddefconfig
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR ANLOGIC_EXTRA_ROOTFS_DIR=$ANLOGIC_EXTRA_ROOTFS_DIR

	#lz4
	mkimage -A $ANLOGIC_ARCH -T ramdisk -C lz4 -n Initrd \
			-d $TARGET_BUILDROOT_OUTPUT_DIR/images/rootfs.cpio.lz4 \
			   $TARGET_BUILDROOT_OUTPUT_DIR/images/uInitrd.lz4

	# clean images rootfs file first
	rm -rf $TARGET_IMG_OUTPUT_DIR/rootfs.*
	rm -rf $TARGET_IMG_OUTPUT_DIR/uInitrd.lz4

	cp $TOP_DIR/$ANLOGIC_BUILDROOT_IMG $TARGET_IMG_OUTPUT_DIR

#ln -rsf $ANLOGIC_ROOTFS_DIR/$ROOTFS_IMG $ANLOGIC_ROOTFS_IMG

	finish_build
}

function build_cleanbuildroot(){
	rm -rf $TARGET_BUILDROOT_OUTPUT_DIR
	rm -rf $TARGET_IMG_OUTPUT_DIR/rootfs.*
	rm -rf $TARGET_IMG_OUTPUT_DIR/uInitrd.lz4
	finish_build
}

function menuconfig_buildroot(){
	check_config ANLOGIC_BUILDROOT_DEFCONFIG || return 0
	BUILDROOT_DIR=$TOP_DIR/buildroot
	TARGET_BUILDROOT_OUTPUT_DIR=$TOP_DIR/$TARGET_BUILDROOT_OUTPUT_DIR

	echo "==========Start building buildroot=========="
	echo "TARGET_BUILDROOT_DIR        = $BUILDROOT_DIR"
	echo "TARGET_BUILDROOT_CONFIG     = $ANLOGIC_BUILDROOT_DEFCONFIG"
	echo "TARGET_BUILDROOT_OUTPUT_DIR = $TARGET_BUILDROOT_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_BUILDROOT_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR $ANLOGIC_BUILDROOT_DEFCONFIG
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR menuconfig
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR savedefconfig

	finish_build
}

function menuconfig_busybox(){
	check_config ANLOGIC_BUILDROOT_DEFCONFIG || return 0
	BUILDROOT_DIR=$TOP_DIR/buildroot
	TARGET_BUILDROOT_OUTPUT_DIR=$TOP_DIR/$TARGET_BUILDROOT_OUTPUT_DIR

	echo "==========Start building buildroot=========="
	echo "TARGET_BUILDROOT_DIR        = $BUILDROOT_DIR"
	echo "TARGET_BUILDROOT_CONFIG     = $ANLOGIC_BUILDROOT_DEFCONFIG"
	echo "TARGET_BUILDROOT_OUTPUT_DIR = $TARGET_BUILDROOT_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_BUILDROOT_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR $ANLOGIC_BUILDROOT_DEFCONFIG
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR busybox-menuconfig
	make -C $BUILDROOT_DIR O=$TARGET_BUILDROOT_OUTPUT_DIR busybox-update-config

	finish_build
}

function build_bootscr(){
	check_config ANLOGIC_BOOTSCR || return 0
	BOOTSCR="$TOP_DIR/device/$TARGET_DIR_NAME/$ANLOGIC_BOOTSCR"
	TARGET_BOOTSCR_OUTPUT_DIR=$TOP_DIR/$TARGET_BOOTSCR_OUTPUT_DIR

	echo "==========Start building bootscr=========="
	echo "TARGET_BOOTSCR            = $BOOTSCR"
	echo "TARGET_BOOTSCR_OUTPUT_DIR = $TARGET_BOOTSCR_OUTPUT_DIR"
	echo "============================================"

	mkdir -p $TARGET_BOOTSCR_OUTPUT_DIR || return
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	mkimage -C none -A arm -T script -d $BOOTSCR $TARGET_BOOTSCR_OUTPUT_DIR/boot.scr
	cp $TARGET_BOOTSCR_OUTPUT_DIR/boot.scr $TARGET_IMG_OUTPUT_DIR

	finish_build
}

function build_cleanbootscr(){
	rm -rf $TARGET_BOOTSCR_OUTPUT_DIR
	rm -rf $TARGET_IMG_OUTPUT_DIR/boot.scr
	finish_build
}

function build_bootgen(){
	check_config ANLOGIC_BOOTGEN_CONFIG || return 0
	echo "========================================="
	echo "TARGET_BOOTGEN_CONFIG     = $ANLOGIC_BOOTGEN_CONFIG"
	echo "TARGET_BOOTGEN_OUTPUT_DIR = $TARGET_IMG_OUTPUT_DIR"
	echo "========================================="
	
	mkdir -p $TARGET_IMG_OUTPUT_DIR || return
	
	$TOP_DIR/tools/bootgen/linux64/bin/albg -w -log info -image $TOP_DIR/device/$TARGET_DIR_NAME/$ANLOGIC_BOOTGEN_CONFIG -arch `echo ${ANLOGIC_TARGET_PRODUCT} | tr [:upper:] [:lower:]` -o $TARGET_IMG_OUTPUT_DIR/BOOT.bin
	
	
	finish_build
}

function build_cleanbootgen(){
	rm -rf $TOP_DIR/bootgen.log
	rm -rf $TARGET_IMG_OUTPUT_DIR/BOOT.bin
	finish_build
}

function build_bootpart(){
	check_config ANLOGIC_BOOTPART_SIZE || return 0
	TARGET_BOOTPART_SIZE=`printf "%d" $ANLOGIC_BOOTPART_SIZE`
	if [ $TARGET_BOOTPART_SIZE -gt 0 ]; then
		echo "========================================="
		echo "TARGET_BOOTPART_SIZE       = $TARGET_BOOTPART_SIZE"
		echo "TARGET_BOOTPART_OUTPUT_DIR = $TARGET_IMG_OUTPUT_DIR"
		echo "========================================="

		mkdir -p $TARGET_IMG_OUTPUT_DIR || return
		mkdir -p $TARGET_BOOTPART_DIR || return

		for f in $ANLOGIC_BOOTPART_FILES; do
			if [ -e $f ]; then
				echo "Copy $f"
				cp -fr $f $TARGET_BOOTPART_DIR/`basename $f`
			else 
				echo "no such file $f"
				echo -e "build_bootpart failed"
				return
			fi
		done

		$TOP_DIR/tools/mkfatfs -s $ANLOGIC_BOOTPART_SIZE -c $TARGET_BOOTPART_DIR $TARGET_IMG_OUTPUT_DIR/boot.fat
	fi

	finish_build
}

function build_cleanbootpart(){
	rm -rf $TARGET_BOOTPART_DIR
	rm -rf $TARGET_IMG_OUTPUT_DIR/boot.fat
	finish_build
}

function build_partition(){
	check_config ANLOGIC_STORAGE_SIZE && check_config ANLOGIC_DOS_PART || return 0
	echo "========================================="
	echo "ANLOGIC_STORAGE_SIZE = $ANLOGIC_STORAGE_SIZE"
	echo "ANLOGIC_DOS_PART     = $ANLOGIC_DOS_PART"
	echo "========================================="

	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	$TOP_DIR/tools/dospart $TARGET_IMG_OUTPUT_DIR/partions 512 $ANLOGIC_STORAGE_SIZE $ANLOGIC_DOS_PART

	finish_build
}

function build_cleanpartition(){
	rm -f $TARGET_IMG_OUTPUT_DIR/partions-*
	finish_build
}

function build_extrafiles(){
	check_config ANLOGIC_IMAGE_EXTRA_FILES || return 0
	echo "========================================="
	echo "TARGET_EXTRA_FILES       = $ANLOGIC_IMAGE_EXTRA_FILES"
	echo "========================================="

	mkdir -p $TARGET_IMG_OUTPUT_DIR || return

	for f in $ANLOGIC_IMAGE_EXTRA_FILES; do
		if [ -e $f ]; then
			echo "Copy $f"
			cp -fr $f $TARGET_IMG_OUTPUT_DIR/`basename $f`
		else
			echo "no such file $f"
			echo -e "build_extrafiles failed"
			return
		fi
	done

	finish_build
}

function build_cleanextrafiles(){
	check_config ANLOGIC_IMAGE_EXTRA_FILES || return 0
	for f in $ANLOGIC_IMAGE_EXTRA_FILES; do
		rm -fr $TARGET_IMG_OUTPUT_DIR/`basename $f`
	done
	finish_build
}

function build_all(){
	echo "========================================="
	echo "TARGET_UBOOT_DIR            = $TOP_DIR/u-boot"
	echo "TARGET_UBOOT_CONFIG         = $ANLOGIC_UBOOT_DEFCONFIG"
	echo "TARGET_UBOOT_OUTPUT_DIR     = $TARGET_UBOOT_OUTPUT_DIR"
	echo "TARGET_KERNEL_DIR           = $TOP_DIR/linux"
	echo "TARGET_ARCH                 = $ANLOGIC_ARCH"
	echo "TARGET_KERNEL_CONFIG        = $ANLOGIC_KERNEL_DEFCONFIG"
	echo "TARGET_KERNEL_DTS           = $ANLOGIC_KERNEL_DTS"
	echo "TARGET_KERNEL_OUTPUT_DIR    = $TARGET_KERNEL_OUTPUT_DIR"
	echo "TARGET_BUILDROOT_DIR        = $TOP_DIR/buildroot"
	echo "TARGET_BUILDROOT_CONFIG     = $ANLOGIC_BUILDROOT_DEFCONFIG"
	echo "TARGET_BUILDROOT_OUTPUT_DIR = $TARGET_BUILDROOT_OUTPUT_DIR"
	echo "TARGET_BOOTSCR              = $ANLOGIC_BOOTSCR"
	echo "TARGET_BOOT_SCR_OUTPUT_DIR  = $TARGET_BOOTSCR_OUTPUT_DIR"
	echo "TARGET_BOOTGEN_CONFIG       = $ANLOGIC_BOOTGEN_CONFIG"
	echo "TARGET_BOOTGEN_OUTPUT_DIR   = $TARGET_IMG_OUTPUT_DIR"
	echo "========================================="

	build_opensbi
	build_uboot
	build_bootgen
	build_bootscr
	build_kernel
	build_buildroot
	build_partition
	build_bootpart
	build_extrafiles

	finish_build
}

function build_cleanall(){
	echo "clean uboot, kernel, rootfs, bootscr, bootgen, images"
	rm -rf $TARGET_OUTPUT_DIR
	rm -rf $BOARD_CONFIG
	rm -rf $TARGET_IMG_OUTPUT_DIR
	finish_build
}

#=========================
# build targets
#=========================

if echo $@|grep -wqE "help|-h"; then
	usage
	exit 0
fi

OPTIONS="${@:-usage}"

for option in ${OPTIONS}; do
	echo "processing option: $option"
	case $option in
		BoardConfig*.mk)
			option=device/$TARGET_DIR_NAME/$option
			;&
		*.mk)
			CONF=$(realpath $option)
			echo "switching to board: $CONF"
			if [ ! -f $CONF ]; then
				echo "not exist!"
				exit 1
			fi

			ln -rsf $CONF $BOARD_CONFIG
			;;
		lunch) build_select_board ;;
		info) build_info ;;
		opensbi) build_opensbi ;;
		fsbl) build_fsbl ;;
		uboot) build_uboot ;;
		ubootmenuconfig) menuconfig_uboot;;
		kernel) build_kernel ;;
		kernelmenuconfig) menuconfig_kernel;;
		buildroot) build_buildroot ;;
		buildrootmenuconfig) menuconfig_buildroot ;;
		busyboxmenuconfig) menuconfig_busybox ;;
		bootscr) build_bootscr ;;
		partition) build_partition ;;
		bootpart) build_bootpart ;;
		bootgen) build_bootgen ;;
		extrafiles) build_extrafiles ;;
		all) build_all ;;
		cleanopensbi) build_cleanopensbi ;;
		cleanfsbl) build_cleanfsbl ;;
		cleanuboot) build_cleanuboot ;;
		cleankernel) build_cleankernel ;;
		cleanbuildroot) build_cleanbuildroot ;;
		cleanbootscr) build_cleanbootscr ;;
		cleanpartition) build_cleanpartition ;;
		cleanbootpart) build_cleanbootpart ;;
		cleanbootgen) build_cleanbootgen ;;
		cleanextrafiles) build_cleanextrafiles ;;
		cleanall) build_cleanall ;;
		*) usage ;;
	esac
done
